/**
 * @file srt_def.h
 * @author liuzl (zhanlin.liu@hopechart.com)
 * @brief
 * @version 0.1
 * @date 2022-04-26
 *
 * @copyright Copyright (C) {2009-2021} 杭州鸿泉物联网技术股份有限公司 All rights reserved
 *
 */
#ifndef __SRT_DEF_H__
#define __SRT_DEF_H__

//#include "common.h"
#include "ofc_types.h"
#include "srt_storage/srt_common_def.h"
#define KEY_OF_ID(id)       ((id)&0x3FFF)

#ifdef __cplusplus
extern "C" {
#endif

typedef struct SrtDef_TDescTag SrtDef_TDesc;

#pragma pack(1)
struct SrtDef_TDescTag {
    UInt16 magic;
    UInt16 crc;
    UInt32 size;
    UInt32 timstamp;
    UInt16 key_count;
    UInt16 version;
};

/**
 * @brief 内存分组定义
 */
struct SrtDef_MemGrpTag {
    /**< 指向Srt内存值存储组首地址 */
    UInt16 typed_grp_offset[kSrtKeyTypeMax];
};
typedef struct SrtDef_MemGrpTag SrtDef_MemGrp;

/**
 * @brief 缺省分组定义
 * 
 * 指向不同类型的缺省值组
 */
struct SrtDef_DefGrpTag {
    /**< 指向Srt缺省值存储组首地址 */
    UInt16 typed_grp_offset[kSrtKeyTypeBin-kSrtKeyTypeU32 + 1];
};
typedef struct SrtDef_DefGrpTag SrtDef_DefGrp;

typedef struct SrtDef_TKeyDescTag SrtDef_TKeyDesc;
#pragma anon_unions
/**
 * @brief Key描述结构
 * 
 * 描述
 */
struct SrtDef_TKeyDescTag {
    union {
        UInt32 id;
        struct {
            UInt32 b_id: 14;        /**< id */
            UInt32 b_perm: 2;       /**< 权限 */
            UInt32 b_group: 4;      /**< 组ID */
            UInt32 b_timestamp: 1;   /**< 是否有时间戳 */
            UInt32 b_notify: 1;     /**< 变化通知 */
            UInt32 b_type: 3;       /**< 类型 */
            UInt32 b_restore: 2;    /**< 恢复出厂级别 */
            UInt32 b_sync: 1;       /**< 是否同步 */
            UInt32 b_persist: 1;    /**< 是否存储 */
            UInt32 b_log: 1;        /**< 是否记录日志 */
            UInt32 b_private: 1;    /**< 私有的 */
            UInt32 b_default: 1;    /**< 是否有缺省值 */
        };
    } key;
    UInt16 memv_grp_index;        /**< 内存值组内索引或者offset */
    UInt16 defv_grp_index;        /**< 缺省值在组内的偏移地址, bin型总是有,如果无效值向有效bitmap的index */
};

struct SrtDef_THeaderTag {
    SrtDef_TDesc header;
    SrtDef_MemGrp  memv_grp;
    SrtDef_DefGrp  defv_grp;
};
typedef struct SrtDef_THeaderTag SrtDef_THeader;

typedef struct SrtDef_BinKeyDescTag SrtDef_BinKeyDesc;
/**
 * @brief Bin型描述
 */
struct SrtDef_BinKeyDescTag {
    UInt8 max_len;                  /**< 最大长度 */
    UInt8 len;                      /**< 缺省值长度 */
    UInt8 value[2];                 /**< 占位符 */
};

typedef struct SrtDef_TsDescTag SrtDef_TsDesc;
/**
 * @brief 属性时间戳描述
 */
struct SrtDef_TsDescTag {
    UInt16 count;                  /**< 属性时间戳个数 */
    UInt16 ts_offset;              /**< 时间戳内存偏移 */
    UInt16 reserved;               /**< 保留 */
    UInt16 arr[1];                 /**< 占位符，属性时间戳id列表 */
};


/**
 * @brief 扩展块项枚举
 * 指向不同扩展块项
 */
typedef struct SrtDef_DefExtDescTag SrtDef_DefExtDesc;
struct SrtDef_DefExtDescTag {
    /**< 自下往上偏移 */
    UInt16 ext_item_offset[kSrtExtItemMax];
};

/**
 * @brief 扩展块头
 */
typedef struct SrtDef_ExtHeaderTag SrtDef_ExtHeader;
struct SrtDef_ExtHeaderTag {
    SrtDef_DefExtDesc ext_desc;
    UInt16 ext_item_count;
    UInt16 ext_size;
};

#pragma pack()

void SrtDef_Undefine(void);

/**
 * @brief 判断Srt定义是否就绪
 * 
 * @return Bool 
 */
Bool SrtDef_IsDefined(void);

/**
 * @brief 获得Srt定义的Key数量
 * 
 * @return 数量
 */
Int32 SrtDef_GetKeyCnt(void);

/**
 * @brief 获得所属组内存偏移
 * @param kdesc 
 * @return <0: 参考错误码 @ref THccMidSrtErrorCode; >=0: 实际偏移位置
 */
Int32 SrtDef_GetMemGrpOffset(const SrtDef_TKeyDesc* kdesc);

/**
 * @brief 获得所属组缺省偏移
 * 
 * @param kdesc 
 * @return <0: 参考错误码 @ref THccMidSrtErrorCode; >=0: 实际偏移位置
 */
Int32 SrtDef_GetDefGrpOffset(const SrtDef_TKeyDesc* kdesc);

/**
 * @brief 获得获取时间戳内存偏移
 * @return Int32 
 */
Int32 SrtDef_GetMemTimeStampOffset(void);

/**
 * @brief 计算Srt所需内存尺寸
 * 
 * @return Int32 
 */
Int32 SrtDef_CalcRequiredMemSize(void);

/**
 * @brief 计算需同步的项数量
 * 
 * @return Int32 
 */
Int32 SrtDef_CalcSyncItemCount(void);

/**
 * @brief 获得Srt定义Key列表
 * 
 * @param key_desc_list 列表指针
 * @return Int32 成功返回Key数量，否则表示错误
 */
Int32 SrtDef_TKeyGetList(const SrtDef_TKeyDesc **key_desc_list);

/**
 * @brief 根据id获取Key描述结构和索引
 * 
 * @param pid id
 * @param index 索引(允许为空)
 * @return const SrtDef_TKeyDesc* 
 */
const SrtDef_TKeyDesc *SrtDef_TKeyGet(UInt32 pid, int *index);

/**
 * @brief 根据索引获取Key描述结构
 * 
 * @param index 索引
 * @return const SrtDef_TKeyDesc* Key描述对象
 */
const SrtDef_TKeyDesc *SrtDef_TKeyGetAt(int index);

int SrtDef_TKeyIndex(const SrtDef_TKeyDesc *self);

/**
 * @brief 从key的描述符中获取bin类型的key描述符
 * @param self: Key描述
 * @return 成功: bin类型的key描述符; 失败: NULL
 */
const SrtDef_BinKeyDesc* SrtDef_TKeyGetBinDesc(const SrtDef_TKeyDesc *self);

/**
 * @brief 从Key描述结构中读取值(即缺省值)
 * 
 * @param self Key描述
 * @param param_value 接收值缓存区
 * @param size 缓冲区尺寸
 * @return int 结果码
 */
int SrtDef_TKeyGetValue(const SrtDef_TKeyDesc *self, UInt8 *param_value, Int32 size);

/**
 * @brief 获得Bin型缺省值长度
 * 
 * @param self Key描述
 * @return int 
 */
int SrtDef_TKeyGetBinValueLen(const SrtDef_TKeyDesc *self);

/**
 * @brief 获得Bin型值最大容量
 * 
 * @param self Key描述
 * @return int 
 */
int SrtDef_TKeyGetBinValueCapacity(const SrtDef_TKeyDesc *self);

//-----新增----//
/**
 * @brief 判断设置的值与缺省值是否一样
 * 
 * @param kdesc 属性描述
 * @param value 设置值
 * @return False 相等; True 不相等 
 */
Bool SrtDef_TKeyIsNotDefaultValue(const SrtDef_TKeyDesc *self, const UInt8 *value, int len);

#ifdef __cplusplus
}
#endif

#endif
